package a1_p04_jw_kw.graph;

import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.DirectedPseudograph;
import org.jgrapht.graph.Pseudograph;

import a1_p04_jw_kw.struct.GraphSetup;
import a1_p04_jw_kw.struct.GraphTransition;
import a1_p04_jw_kw.struct.Node;

public class GraphCreater {
	GraphSetup gs;
	Graph<Node, DefaultWeightedEdge> g;
	
	public GraphCreater(GraphSetup setup) {
		this.gs = setup;
		
	}
	
	public void createGraph() {
		createGraphByAttribute();
		//createDirectedWeightedGraph();

	}

	private void createGraphByAttribute() {
//		if (gs.isDirected && gs.isWeighted) {
//			createDirectedWeightedGraph();
//			
//		} else if (gs.isUndirected && gs.isWeighted) {
//			createWeightedGraph();
//
//		} else if (gs.isDirected && !gs.isWeighted) {
//			createDirectedGraph();
//
//		} else if (gs.isUndirected && !gs.isWeighted) {
//			createUndirectedGraph();
//
//		}
		
		if (gs.isDirected) {
			createDirectedWeightedGraph();
			
		} else {
			createWeightedGraph();
			
		}
		
	}
	
	private void createDirectedWeightedGraph() {
		DirectedPseudograph<Node, DefaultWeightedEdge> dwg = (DirectedPseudograph<Node, DefaultWeightedEdge>) new DirectedPseudograph<Node, DefaultWeightedEdge>(DefaultWeightedEdge.class);
		for (GraphTransition transition : gs.transitions) {
			dwg.addVertex(transition.node1);
			dwg.addVertex(transition.node2);
	
		}
		
		for (GraphTransition transition : gs.transitions) {
			dwg.addEdge(transition.node1, transition.node2);
			
			//add the inverted edge if the graph is undirected
			if (gs.isUndirected) {
				dwg.addEdge(transition.node2, transition.node1);
				
			}
		
		}
		
		for (GraphTransition transition : gs.transitions) {
			dwg.setEdgeWeight(dwg.getEdge(transition.node1, transition.node2),Double.parseDouble(transition.weight));
			
			//add the inverted edges weight if the graph is undirected
			if (gs.isUndirected) {
				dwg.setEdgeWeight(dwg.getEdge(transition.node2, transition.node1),Double.parseDouble(transition.weight));
				
			}			
				
		}
		
		g = dwg;
		
	}
	
	private void createWeightedGraph() {
		Pseudograph<Node, DefaultWeightedEdge> dwg = (Pseudograph<Node, DefaultWeightedEdge>) new Pseudograph<Node, DefaultWeightedEdge>(DefaultWeightedEdge.class);
		for (GraphTransition transition : gs.transitions) {
			dwg.addVertex(transition.node1);
			dwg.addVertex(transition.node2);
		}
		
		
		
		for (GraphTransition transition : gs.transitions) {
			DefaultWeightedEdge e = new DefaultWeightedEdge();
			dwg.setEdgeWeight(e,Double.parseDouble(transition.weight));
			dwg.addEdge(transition.node1, transition.node2,e);
		
		}
		
//		for (GraphTransition transition : gs.transitions) {
//			dwg.setEdgeWeight(dwg.getEdge(transition.node1, transition.node2),Double.parseDouble(transition.weight));
//				
//		}
		g = dwg;
		
	}
//	
//	private void createDirectedGraph() {
//		DefaultDirectedGraph<Node, DefaultWeightedEdge> dwg = (DefaultDirectedGraph<Node, DefaultWeightedEdge>) new DefaultDirectedGraph<Node, DefaultWeightedEdge>(DefaultWeightedEdge.class);
//		for (GraphTransition transition : gs.transitions) {
//			dwg.addVertex(transition.node1);
//			dwg.addVertex(transition.node2);
//	
//		}
//		
//		for (GraphTransition transition : gs.transitions) {
//			dwg.addEdge(transition.node1, transition.node2);
//		
//		}
//
//		System.out.println(dwg.toString());
//		g = dwg;
//		
//	}	
//
//	private void createUndirectedGraph() {
//		
//		//TODO: 
//		SimpleGraph<Node, DefaultWeightedEdge> dwg = (SimpleGraph<Node, DefaultWeightedEdge>) new SimpleGraph<Node, DefaultWeightedEdge>(DefaultWeightedEdge.class);
//		for (GraphTransition transition : gs.transitions) {
//			dwg.addVertex(transition.node1);
//			dwg.addVertex(transition.node2);
//	
//		}
//		
//		for (GraphTransition transition : gs.transitions) {
//			dwg.addEdge(transition.node1, transition.node2);
//		
//		}
//
//		System.out.println(dwg.toString());
//		g = dwg;
//		
//	}	
	
	public Graph<Node, DefaultWeightedEdge> getGraph() {
		if (gs.isDirected) {
			return (DirectedPseudograph<Node, DefaultWeightedEdge>)this.g;
			
		} else {
			return (Pseudograph<Node, DefaultWeightedEdge>)this.g;
			
		}
		
		
	}

	
}
